home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Gold Collection
/
Software Vault - The Gold Collection (American Databankers) (1993).ISO
/
cdr09
/
readpaf.zip
/
READPAF.PAS
< prev
Wrap
Pascal/Delphi Source File
|
1993-06-16
|
9KB
|
326 lines
{$R-} {Range checking off}
{$B+} {Boolean complete evaluation on}
{$S+} {Stack checking on}
{$N-} {No numeric coprocessor}
{$M 65500,16384,655360} {Turbo 3 default stack and heap}
{$I-}
PROGRAM readpaf;
{This program is an abbreviated version of my program FR2SDF. This program
is intended to demonstrate how to use Turbo Pascal to read PAF files. It is
strongly recommended that you send $5.00 to:
The Church of Jesus Christ of Latter-Day Saints
Family History Department
50 East North temple Street
Salt Lake City, Utah 84150
and ask for "Personal Ancestral File Family Records Data Structure
Description". This document describes gives full technical details on the
data structures used in PAF. This information will be needed to expand
this program to read all the data in all the PAF files.
This program will only read the INDIV2 and NAME2 files of PAF. It will
write a file with the person's RIN number, all four name fields, the sex
field, older sibling RIN, own marriage MRIN, and parent's marriage MRIN.
It does not convert the dates, (which is a real experience!) or the
rest of the data in the INDIV2, MARR2, and NOTE2 files. This is left, as
they say, as an exercise for the reader.
This program requires at least version 4.0 of Turbo Pascal. It should
work with later versions, but has only been tested with version 4.0.}
Uses
Crt;
type
Short_Date = Array[1..3] of Byte;
Long_Date = Array[1..4] of Byte;
String4 = String[4];
String5 = String[5];
String16 = String[16];
String20 = String[20];
Name2 = record
Left_Link : Word;
Name : Array[1..17] of Char;
Right_Link : Word;
end;
Indiv2 = record
SurName : Word;
Given_1_Name : Word;
Given_2_Name : Word;
Given_3_Name : Word;
Title : Word;
Sex : Char;
Birth_Date : Long_Date;
Birth_Place_1 : Word;
Birth_Place_2 : Word;
Birth_Place_3 : Word;
Birth_Place_4 : Word;
Christening_Date : Long_Date;
Christening_Place_1 : Word;
Christening_Place_2 : Word;
Christening_Place_3 : Word;
Christening_Place_4 : Word;
Death_Date : Long_Date;
Death_Place_1 : Word;
Death_Place_2 : Word;
Death_Place_3 : Word;
Death_Place_4 : Word;
Burial_Date : Long_Date;
Burial_Place_1 : Word;
Burial_Place_2 : Word;
Burial_Place_3 : Word;
Burial_Place_4 : Word;
Baptism_Date : Short_Date;
Baptism_Temple : Word;
Endowment_Date : Short_Date;
Endowment_Temple : Word;
Sealing_Date : Short_Date;
Sealing_Temple : Word;
Older_Sibling : Word;
Own_Marriage : Word;
Parent_Marriage : Word;
ID_Number : Array[1..10] of Char;
Note_Pad : Word;
end;
VAR
Name2File : file of Name2;
Indiv2File : file of Indiv2;
ThisName2 : Name2;
ThisIndiv2 : Indiv2;
Indiv2Txt : Text;
Command_Line_Path : String[127];
FileName : String[127];
const
IOVal : Integer = 0;
IOErr : Boolean = False;
Use_Name_File : Boolean = True;
{
The routine IOCheck, along with the global declarations
IOFlag and IOErr, should be placed in any program where you
want to handle your own I/O error checking.
}
procedure IOCheck;
{
This routine sets IOErr equal to IOresult, then sets
IOFlag accordingly. It also prints out a message on
the 24th line of the screen, then waits for the user
to hit any character before proceding.
}
var
Ch : Char;
begin
IOVal := IOresult;
IOErr := (IOVal <> 0);
if IOErr then begin
{GotoXY(1,24);} ClrEol; { Clear error line }
Write(Chr(7));
case IOVal of
$02 : Write('File not found ', FileName);
$03 : Write('Path not found ', Command_Line_Path);
$04 : Write('File not open');
$10 : Write('Error in numeric format');
$20 : Write('Operation not allowed on a logical device');
$21 : Write('Not allowed in direct mode');
$22 : Write('Assign to standard files not allowed');
$90 : Write('Record length mismatch');
$91 : Write('Seek beyond end of file');
$99 : Write('Unexpected end of file');
$F0 : Write('Disk write error');
$F1 : Write('Directory is full');
$F2 : Write('File size overflow');
$FF : Write('File disappeared')
else Write('Unknown I/O error: ',IOVal:3)
end;
{Read(Kbd,Ch)} HALT
end
end; { of proc IOCheck }
{procedure dirlist;
begin
end; }
function Get_Name (Name_Pointer : Word) : String16;
{ This function will take a name pointer value, look it up in the
Name File, and return the value. If the name pointer value is
zero (null), then a blank name is returned.}
Var
Counter : Integer;
Name_From_File : Array[1..16] of Char;
Const
Space16 : String16 = ' ';
Begin
If Name_Pointer <> 0 Then
Begin
Seek(Name2File, Name_Pointer);
IOCheck;
Read(Name2File, ThisName2);
IOCheck;
With ThisName2 Do Begin
Counter := 1;
While Name[Counter] <> #00 Do Begin
Name_From_File[Counter] := Name[Counter];
Inc(Counter);
end;
end;
While Counter < 17 Do Begin
Name_From_File[Counter] := ' ';
Inc(Counter);
end;
Get_Name := Name_From_File;
end
else
Get_Name := Space16;
end; {function Get_Name}
function Convert_To_String ( Rin : Word) : String5;
{takes an integer and converts it to a 5 byte ASCII string}
Var
Temp_String : String5;
Begin
Str(Rin:5, Temp_String);
Convert_To_String := Temp_String;
end; {function Convert_To_String}
procedure Write_Indiv_File
(Var r1 : String5;
sn : String16;
n1 : String16;
n2 : String16;
n3 : String16;
sx : Char;
os : String5;
om : String5;
pm : String5);
Begin
If sx = #00 Then sx := ' ';
WriteLn(Indiv2Txt, r1, sn, n1, n2, n3, sx, os, om, pm);
IOCheck;
end; {procedure Write_Indiv_File}
procedure Convert_Indiv2;
Var
rec_no : String5;
Counter : Integer;
Const
Event_Bir : String4 = 'BIR ';
Event_Chr : String4 = 'CHR ';
Event_Dea : String4 = 'DEA ';
Event_Bur : String4 = 'BUR ';
begin
{Determine which record we have}
Str((FilePos(Indiv2File) - 1):5, rec_no);
GotoXY(1,9); {Display record being processed on the screen}
WriteLn('Individual Record being converted: ', rec_no);
With ThisIndiv2 Do {Get the values from the record}
Begin
Write_Indiv_File {Write the Indiv2 File}
(rec_no,
Get_Name(SurName),
Get_Name(Given_1_Name),
Get_Name(Given_2_Name),
Get_Name(Given_3_Name),
Sex,
Convert_To_String(Older_Sibling),
Convert_To_String(Own_Marriage),
Convert_To_String(Parent_Marriage));
end;
end; {procedure Convert_Indiv2}
procedure Open_Files;
Begin
If ParamCount > 0 Then {This pulls the path from the}
Command_Line_Path := ParamStr(1) {command line if it is entered.}
else
Command_Line_Path := '';
FileName := Concat(Command_Line_Path, 'NAME2.DAT');
Assign(Name2File,FileName);
Reset(Name2File);
IOCheck;
FileName := Concat(Command_Line_Path, 'INDIV2.DAT');
Assign(Indiv2File,FileName);
Reset(Indiv2File);
IOCheck;
FileName := 'INDIV2.TXT';
Assign(Indiv2Txt,FileName);
Rewrite(Indiv2Txt);
IOCheck;
end; {procedure Open_Files}
procedure Close_Files;
Begin
Close(Name2File);
IOCheck;
Close(Indiv2File);
IOCheck;
Close(Indiv2Txt);
IOCheck;
end; {procedure Close_Files}
Begin
ClrScr;
WriteLn;
WriteLn('READPAF - an abbreviated version of FR2SDF');
WriteLn('to demonstrate how to read PAF files.');
WriteLn('Copyright (c) 1989 by Joseph R. Wood.');
WriteLn('Permission is granted to copy for');
WriteLn('noncommercial or nonprofit use only.');
WriteLn('All other rights reserved.');
WriteLn;
Open_Files;
Read(Indiv2File, ThisIndiv2); {Do a priming read and throw away}
IOCheck; {the file's header record}
With ThisIndiv2 Do
While not eof(Indiv2File)
DO Begin
Read(Indiv2File, ThisIndiv2);
IOCheck;
Convert_Indiv2;
End;
Close_Files;
WriteLn;
WriteLn('READPAF Terminated Normally.');
End.